package model.map;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.Set;

import model.area_effect.MapAreaOfEffect;
import model.area_effect.Trap;
import model.entity.Entity;
import model.item.InventoryItem;
import model.item.MapGold;

/**
 * Visitor that goes around to each tiles on the game map
 * and pulls the names of all savable things on that tile.
 * @author Zachary
 *
 */
public class SaveVisitor extends MapVisitor {
	private SaveMap save;
	
	/**
	 * Constructor for SaveVisitor.
	 * @param map
	 * @param save
	 */
	public SaveVisitor(SaveMap save){
		this.save = save;
	}
	
	/**
	 * Save everything that is savable on the map.
	 */
	public void visit(GameMap gameMap) {
		MapPoint boundary = gameMap.getBoundary();
		int xDim = boundary.getXCoordinate();
		int yDim = boundary.getYCoordinate();
		
		// for each tile
		for(int x = 0;x<=xDim;++x){
			for(int y = 0;y<=yDim;++y){
				MapPoint point = new MapPoint(x,y);
				if(!MapPoint.isValidLocation(point))
					continue;
				MapTileState state = gameMap.getTileState(point);
				if(state != null){
					Queue<String> renderables = new LinkedList<String>();
					if(state.getName().equals("Shrouded"))
						renderables = state.pullDataFromMap();
					this.save.saveState(point, state.getName(),renderables);
				}
				
				List<Entity> ents = gameMap.getEntitiesOnTile(point);
				for(Entity e : ents)
					this.save.saveEntity(point, e.getName());
				
				List<InventoryItem> items = gameMap.getInventoryItemsOnTile(point);
				for(InventoryItem i : items)
					this.save.saveItem(point, i.getName());
				
				List<MapAreaOfEffect> mapAoEs = gameMap.getMapAreaOfEffect(point);
				for(MapAreaOfEffect aoe : mapAoEs)
					this.save.saveMapAoE(point, aoe.getName());
				
				List<Trap> traps = gameMap.getTraps(point);
				for(Trap t : traps)
					this.save.saveTrap(point, t.getName());
				
				List<MapGold> gold = gameMap.getMapGoldOnTile(point);
				for(MapGold g : gold)
					this.save.saveGold(point, g.getName());
			}
		}
	}

	/**
	 * Save the list of shrouded entities for future use when loading.
	 * @return
	 */
	public String addShroudedData(){
		Set<Entity> entitySet = MapVisitor.getCurrentlyShroudedEntities().keySet();
		StringBuilder shroudedEnts = new StringBuilder();
		shroudedEnts.append("[ShroudedEntities]");
		for(Entity entity : entitySet){
			MapPoint point = MapVisitor.getCurrentlyShroudedEntities().get(entity);
			shroudedEnts.append(point.toString());
			shroudedEnts.append(" ");
			shroudedEnts.append(entity.getName());
			shroudedEnts.append(";");
		}
		shroudedEnts.append("\n");
		return shroudedEnts.toString();
	}
}
